#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <assert.h>
#include <unordered_map>
#include "../comm/logger.hpp"
#include "../comm/util.hpp"
#include </usr/include/mysql/mysql.h>
namespace ns_model
{
    using namespace ns_util;
    class Question
    {
    public:
        int _id;                 // 题目编号(唯一)
        std::string _title;      // 题目标题
        std::string _difficulty; // 题目难度
        int _cpu_limit;          // 时间限制(s)
        int _mem_limit;          // 空间限制(KB)
        // 这三个内容是封装在文件里的
        std::string _desc;   // 题目描述
        std::string _header; // 题目预设代码
        std::string _tail;   // 题目测试用例(需要和预设代码拼成完整代码)
    };
    const std::string HOST = "localhost";
    const std::string USER = "oj_manager";
    const std::string PASSWD = "@Gxy6666";
    const std::string DBNAME = "questions";
    const int PORT = 3306;
    class Model
    {
    public:
        bool QueryMySql(const std::string &sql, std::vector<Question> &out)
        {
            // 创建MySQL句柄
            MYSQL *mysql = mysql_init(nullptr);
            // 连接数据库
            if (!mysql_real_connect(mysql,HOST.c_str(),USER.c_str(),PASSWD.c_str(),DBNAME.c_str(),PORT,nullptr,0))
            {
                FLOG("数据库连接失败,请检查配置");
                return false;
            }
            //设置字符集
            mysql_set_character_set(mysql, "utf8");
            ILOG("连接数据库成功");
            //执行sql语句
            if(mysql_query(mysql,sql.c_str())!=0)
            {
                ELOG("sql语句执行错误,请检查sql语句");
                return false;
            }
            //保存结果集到本地
            MYSQL_RES* res=mysql_store_result(mysql);
            //遍历获取结果,res相当于是一个行列的二维数组
            int row=mysql_num_rows(res);
            int col=mysql_num_fields(res);
            Question q;
            for(int i=0;i<row;i++)
            {
                MYSQL_ROW row = mysql_fetch_row(res);
                q._id=std::stoi(row[0]);
                q._title=row[1];
                q._difficulty=row[2];
                q._cpu_limit=std::stoi(row[3]);
                q._mem_limit=std::stoi(row[4]);
                q._desc=row[5];
                q._header=row[6];
                q._tail=row[7];
                out.push_back(q);
            }
            //释放结果空间
            mysql_free_result(res);
            //关闭mysql连接
            mysql_close(mysql);
            return true;
        }
        bool GetAllQuestions(std::vector<Question> &out)
        {
            std::string sql="select * from";
            sql+=" questions";
            //for debug
            std::cout<<sql<<std::endl;
            return QueryMySql(sql, out);
        }
        bool GetOneQuestion(int id, Question &q)
        {
            std::string sql="select * from";
            sql +=" questions where id=";
            sql +=std::to_string(id);
            std::vector<Question> result;
            //for debug
            std::cout<<sql<<std::endl;
            if(QueryMySql(sql, result))
            {
                if(result.size() == 1){
                    q= result[0];
                    return true;
                }
            }
            return false;
        }
        Model()
        {
        }
        ~Model()
        {
        }
    };
}